package ${map.basePackage}.controller;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.rulian.base.common.dto.ExcelBook;
import cn.rulian.base.common.dto.ExcelSheet;
import cn.rulian.base.common.dto.Message;
import cn.rulian.base.common.util.Num;
import cn.rulian.base.common.vo.Result;
import ${curd.boPath};
import ${map.basePackage}.service.${map.boName}Service${temp};
import ${map.basePackage}.vo.${map.boName}Vo;

/**
 * ${curd.name} Controller
 */

@Controller
@RequestMapping("/${map.projectName}/${map.groupName}/${map.boName_low}")
public class ${map.boName}Controller${temp} {
	
	@Autowired
	private ${map.boName}Service${temp} service;
	
	private final String path="${map.projectName}/${map.groupName}/${map.boName_low}_"; //页面基本路径

	/**
	 * 页面基本路径
	 */
	private String getPath()
	{
		return path;
	}
	
	/**
	 * 列表页面
	 */
	@RequestMapping("/listPage")
	public String listPage() {
		return this.getPath()+"list";
	}

	/**
	 * 查询
	 */
	@RequestMapping("/listData")
	@ResponseBody
	public Result listData(${map.boName}Vo vo) {
		return service.query(vo);
	}

	/**
	 * 增加页面
	 */
	@RequestMapping("/addPage")
	public String addPage() {
		return this.getPath()+"add";
	}

	/**
	 * 增加
	 */
	@RequestMapping("/add")
	@ResponseBody
	public Message add(${map.boName}Vo vo) {
		Message rm = new Message();
		${map.boName} bo = vo.getObj();
		try {
			
			service.save(bo);
			
			rm.setMsg("保存成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("保存失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}

	/**
	 * 修改页面
	 */
	@RequestMapping("/updatePage")
	public String updatePage(Model model, Long id) {
		model.addAttribute("bo", service.findOne(id));
		return this.getPath()+"update";
	}

	/**
	 * 修改
	 */
	@RequestMapping("/update")
	@ResponseBody
	public Message update(${map.boName}Vo vo,Long id) {
		Message rm = new Message();
		try {
			${map.boName} obj = vo.getObj();
			${map.boName} bo = service.findOne(id);
			//xx.copyObjectField(obj, bo,"addTime"); //属性值copy
		<#list updateFields as item>
			bo.set${item.fieldName?cap_first}(obj.get${item.fieldName?cap_first}());
    	</#list>
			service.save(bo);
			
			rm.setMsg("保存成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("保存失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}

	/**
	 * 删除
	 */
	@RequestMapping("/delete")
	@ResponseBody
	public Message delete(Long ids[]) {
		Message rm = new Message();
		try {
			for(Long id:ids)
			{
				service.delete(id);
			}
			
			rm.setMsg("删除成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("删除失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}
	
	/**
	 * 详情页面
	 */
	@RequestMapping("/detailPage")
	public String detailPage(Model model, Long id) {
		model.addAttribute("bo", service.findOne(id));
		return this.getPath()+"detail";
	}

	/**
	 * 导出Excel
	 * @throws Exception 
	 */
	@RequestMapping("/exportExcel")
	public void exportExcel(HttpServletResponse response,${map.boName}Vo vo,String type) throws Exception {
		
		File file = new File("aaa.xls");
		jxl.write.WritableWorkbook book = Workbook.createWorkbook(file); //工作薄

		List<${map.boName}> allDataList=service.QueryExcelData(vo); //取得导出数据
		ExcelBook<${map.boName}> excelBook = this.buildExcelData(allDataList, type); //按维度进行数据加工
		String bookName = excelBook.getName(); //Excel文件名称
		List<ExcelSheet<${map.boName}>> sheetList = excelBook.getSheetList(); //各Sheet列表
		if(sheetList!=null && sheetList.size() > 0)
		{
			for(ExcelSheet<${map.boName}> excelSheet:sheetList)
			{
				String sheetName = excelSheet.getName(); //名称
				List<${map.boName}> oneList = excelSheet.getDataList(); //数据列表
				
				jxl.write.WritableSheet sheet = book.createSheet(sheetName, 0); //工作表
				
				//设置行高
				sheet.getSettings().setDefaultRowHeight(350); //设置所有行默认行高
				sheet.setRowView(0, 700);//第1行 高度
				sheet.setRowView(1, 400);//第2行 高度
				
				//设置个别列宽
				//sheet.setColumnView(2, 12);//宽度设置
				
				//定义格式
				//主标题格式
				WritableCellFormat formatterTitle= new WritableCellFormat(); //标题格式
				formatterTitle.setAlignment(Alignment.CENTRE);//水平对齐
				formatterTitle.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				//WritableFont font = new WritableFont(WritableFont.createFont("ＭＳ Ｐゴシック"), 18, WritableFont.BOLD, false); //黑体
				WritableFont font = new WritableFont(WritableFont.TAHOMA, 18, WritableFont.BOLD, false);
				formatterTitle.setFont(font);
				
				//列标题格式
				WritableCellFormat formatterColumnTitle= new WritableCellFormat(); //列标题格式
				formatterColumnTitle.setAlignment(Alignment.CENTRE);//水平对齐
				formatterColumnTitle.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				formatterColumnTitle .setBackground(Colour.GRAY_25);//背景色
				formatterColumnTitle.setBorder(Border.ALL, BorderLineStyle.THIN);//边框线  所有边框 细线

				//普通内容格式
				WritableCellFormat formatterCon= new WritableCellFormat(); //内容格式
				formatterCon.setAlignment(Alignment.CENTRE);//水平对齐
				formatterCon.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				formatterCon.setBorder(Border.ALL, BorderLineStyle.THIN);//边框线  所有边框 细线
				
				//合计行格式
				WritableCellFormat formatterSum= new WritableCellFormat(); //合计格式
				formatterSum.setAlignment(Alignment.CENTRE);//水平对齐
				formatterSum.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				formatterSum.setBorder(Border.ALL, BorderLineStyle.THIN);//边框线  所有边框 细线
				WritableFont font_sum = new WritableFont(WritableFont.TAHOMA, 10, WritableFont.BOLD, false);
				formatterSum.setFont(font_sum);
				
			<#assign k=0 />
			<#list listFields as item>
				<#assign k=k+1 />
    		</#list>
				//输出标题
				sheet.mergeCells(0, 0, ${k}, 0); //合并单元格（标题）
				sheet.addCell(creatLabel(0,0,"${curd.name}（"+sheetName+"）",formatterTitle));

				//输出列标题
				int rowNum=1; //行号
				int columnNum=0; //列号
				
				sheet.addCell(creatLabel(rowNum,columnNum++,"序号",formatterColumnTitle));
			<#list listFields as item>
				sheet.addCell(creatLabel(rowNum,columnNum++,"${item.showName!item.fieldName}",formatterColumnTitle));
    		</#list>
				
				//合计项
			<#list sumFields as item>
				<#if item.fieldType == "java.lang.Integer" || item.fieldType == "java.lang.Short" || item.fieldType == "java.lang.Long">
				long ${item.fieldName}Sum = 0; // ${item.showName!item.fieldName}
				<#elseif item.fieldType == "java.lang.Double" || item.fieldType == "java.lang.Float">
				double ${item.fieldName}Sum = 0; // ${item.showName!item.fieldName}
				</#if>
    		</#list>
			
				if(oneList != null && oneList.size() > 0)
				{
					SimpleDateFormat formatterDate = new SimpleDateFormat("yyyy-MM-dd"); //日期格式化
					SimpleDateFormat formatterTime = new SimpleDateFormat("yyyy-MM-dd HH:mm"); //时间格式化
					//SimpleDateFormat formatterTime2 = new SimpleDateFormat("yyyy-MM-dd HH:mm"); //时间格式化2
					
					//展示数据
			<#list listFields as item>
					String ${item.fieldName}Str = ""; // ${item.showName!item.fieldName}
    		</#list>
					
					for(int i = 0; i < oneList.size(); i++)
			    	{
						${map.boName} bo = oneList.get(i); 
						rowNum++;
						columnNum=0;
						
						//展示数据初始化
			<#list listFields as item>
						${item.fieldName}Str = ""; // ${item.showName!item.fieldName}
    		</#list>
						
						//展示数据赋值
			<#list listFields as item>
				<#if item.fieldType == "java.lang.Boolean">
					<#-- 02 开关  -->
					<#if item.addType == "B02">
						if(bo.get${item.fieldName?cap_first}()!= null){	${item.fieldName}Str = bo.get${item.fieldName?cap_first}()?"是":"否";	} //${item.showName!item.fieldName}
	           		<#-- 是否  -->
	           		<#else>
						if(bo.get${item.fieldName?cap_first}() != null){	${item.fieldName}Str = bo.get${item.fieldName?cap_first}()?"开":"关";		} //${item.showName!item.fieldName}
	           		</#if>
	           	<#elseif item.fieldType == "java.util.Date">
		           	<#--  时间  -->
	           		<#if (item.addType == "DT03" || item.addType == "DT04")>
						if(bo.get${item.fieldName?cap_first}() != null){	${item.fieldName}Str = formatterTime.format(bo.get${item.fieldName?cap_first}());	} //${item.showName!item.fieldName}
	           		<#--  日期 -->
	           		<#else>
						if(bo.get${item.fieldName?cap_first}() != null){	${item.fieldName}Str = formatterDate.format(bo.get${item.fieldName?cap_first}());	} //${item.showName!item.fieldName}
	           		</#if>
				<#elseif item.otherBo>
						if(bo.get${item.fieldName?cap_first}() != null){	${item.fieldName}Str = bo.get${item.fieldName?cap_first}().get${item.parameter?cap_first}();	} //${item.showName!item.fieldName}
	           	<#else>
						if(bo.get${item.fieldName?cap_first}() != null){	${item.fieldName}Str = bo.get${item.fieldName?cap_first}().toString();	} //${item.showName!item.fieldName}
	           	</#if>
    		</#list>
						
						//输出一行数据
			    		sheet.addCell(creatLabel(rowNum,columnNum++,(i+1)+"",formatterCon)); 
			<#list listFields as item>
			    		sheet.addCell(creatLabel(rowNum,columnNum++,${item.fieldName}Str ,formatterCon)); // ${item.showName!item.fieldName}
    		</#list>
			    		
			    		//合计项累加
			<#list sumFields as item>
				<#if item.fieldType == "java.lang.Integer" || item.fieldType == "java.lang.Short" || item.fieldType == "java.lang.Long">
						if(bo.get${item.fieldName?cap_first}()!=null)
						{
							${item.fieldName}Sum += bo.get${item.fieldName?cap_first}();
						}
				<#elseif item.fieldType == "java.lang.Double" || item.fieldType == "java.lang.Float">
						if(bo.get${item.fieldName?cap_first}()!=null)
						{
							${item.fieldName}Sum = Num.add(${item.fieldName}Sum, bo.get${item.fieldName?cap_first}());
						}
				</#if>
    		</#list>
			    	}
					
					//表格增加合计项
					rowNum++;
					columnNum = 0;
					sheet.setRowView(rowNum, 400);//合计行 高度
		    		
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"",formatterSum)); 
			<#list listFields as item>
				<#if item.canSum>
			    	sheet.addCell(creatLabel(rowNum,columnNum++,${item.fieldName}Sum+"" ,formatterSum)); // ${item.showName!item.fieldName}
				<#elseif item.sumTitle>
					sheet.addCell(creatLabel(rowNum,columnNum++,"合计" ,formatterSum)); //${item.showName!item.fieldName}
				<#else>
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // ${item.showName!item.fieldName}
	           	</#if>
    		</#list>
    		
				}
			}
		}
		
		//-------------------------------

		book.write();
		book.close();

		FileInputStream f = new FileInputStream(file);
		byte[] fb = new byte[f.available()];
		f.read(fb);
		response.setHeader("Content-disposition", "attachment; filename=" + new String((bookName + ".xls").getBytes("gb2312"), "iso8859-1"));
		ByteArrayInputStream bais = new ByteArrayInputStream(fb);
		int b;
		while ((b = bais.read()) != -1)
		{
			response.getOutputStream().write(b);
		}
		response.getOutputStream().flush();
		f.close();
		
	}
	
	private Label creatLabel(int rowNum,int columnNum,String con,WritableCellFormat formatter) //行，列，内容 ，格式化
	{  
		 return new Label(columnNum, rowNum, con,formatter);   
	}  
	
	/**
	 * 从不同维度，构建Excel导出所需要的数据
	 */
	private ExcelBook<${map.boName}> buildExcelData(List<${map.boName}> list,String exportType)
	{
		ExcelBook<${map.boName}> book = new ExcelBook<${map.boName}>();
		
	<#list listFields as item>
		<#if item.excelType>
		String ${item.fieldName}Type = "${item.fieldName}"; //维度：${item.showName!item.fieldName}
		if(${item.fieldName}Type.equals(exportType))
		{
			book.setName("${curd.name}（分${item.showName!item.fieldName}）");
		}
		</#if>
	</#list>	
		
		if("all".equals(exportType))
		{//不分表
			book.setName("${curd.name}");
		}

		//根据维度（sheetName）不同，对数据分表
		Map<String,List<${map.boName}>> map =new HashMap<String,List<${map.boName}>>(); 
		String sheetName = null;
		for(${map.boName} bo:list)
		{
		
	<#list listFields as item>
		<#if item.excelType>
			if(${item.fieldName}Type.equals(exportType))
			{
				book.setName("${curd.name}（分${item.showName!item.fieldName}）");
				if(bo.get${item.fieldName?cap_first}()!=null)
				{
				<#if item.otherBo>
					sheetName = bo.get${item.fieldName?cap_first}().get${item.parameter?cap_first}();
				<#else>
					sheetName = bo.get${item.fieldName?cap_first}();
				</#if>
				}
				else
				{
					sheetName="无${item.showName!item.fieldName}";
				}
			}
		</#if>
	</#list>	
	
			if("all".equals(exportType))
			{//不分表
				sheetName="全部";
			}
			
			List<${map.boName}> dataList = map.get(sheetName);
			if(dataList==null)
			{
				dataList = new ArrayList<>();
			}
			dataList.add(bo);
			map.put(sheetName, dataList);
		}
		
		//转换Map,得到数据表列表
		List<ExcelSheet<${map.boName}>> sheetList = new ArrayList<>();
		for (Map.Entry<String, List<${map.boName}>> m : map.entrySet()) 
		{
			ExcelSheet<${map.boName}> sheet = new ExcelSheet<${map.boName}>();
			sheet.setName(m.getKey());
			sheet.setDataList(m.getValue());
			sheetList.add(sheet);
		} 
		
		if(sheetList.size()==0)
		{
			ExcelSheet<${map.boName}> sheet = new ExcelSheet<${map.boName}>();
			sheet.setName("全部");
			sheet.setDataList(new ArrayList<${map.boName}>());
			sheetList.add(sheet);
		}
		
		book.setSheetList(sheetList);
		
		return book;
	}
	
}
